# -*- coding: utf-8 -*-

from django.forms import Field, CharField, TextInput, fields
from models import retrieveNamedObjects, Tag
from custom_exceptions import ArgumentNoneOrEmptyError

class SplittingTextInput(TextInput):
    """
    A TextInput that renders list of values as space-separated
    """
    def __init__(self, attrs = None, separator = ' '):
        self.separator = separator
        super(SplittingTextInput, self).__init__(attrs)

    def render(self, name, value, attrs=None):
        if value is not None:
            value = self.separator.join(value)
        else:
            value = ''
        return super(SplittingTextInput, self).render(name, value, attrs)

class SeparatedStringsField(Field):
    """
    A set of strings separated by a separator string.
    """
    widget = SplittingTextInput

    def __init__(self, separator = ' ', *args, **kwargs):
        if separator is None or separator == '':
            raise ArgumentNoneOrEmptyError('separator')
        super(SeparatedStringsField, self).__init__(*args, **kwargs)
        self.separator = separator

    def clean(self, value):
        if not value:
            return []
        super(SeparatedStringsField, self).clean(value)
        string_list = value.split(self.separator)
        result_list = []
        for item in string_list:
            item = item.strip()
            if item != '':
                result_list.append(item)
        return result_list

class ModelSeparatedStringsField(SeparatedStringsField):
    """
    A set of separated strings that are treated as values of a model field.
    The field should be string
    """
    widget = SplittingTextInput
    default_error_messages = { 'invalid_field_name' : u'Model %s does not contain field %s'
    }

    def __init__(self, model, field_name, separator = ' ', *args, **kwargs):
        kwargs['separator'] = separator
        super(ModelSeparatedStringsField, self).__init__(*args, **kwargs)
        self.model = model
        self.field_name = field_name

        # This will check that the field does exist and throw models.FieldDoesNotExist otherwise
        self.model._meta.get_field_by_name(self.field_name)

    def clean(self, value):
        string_list = super(ModelSeparatedStringsField, self).clean(value)
        string_list = set(string_list) # Remove duplicates
        return retrieveNamedObjects(self.model, self.field_name, string_list)

def TagField():
    return ModelSeparatedStringsField(Tag, 'name')

class ForeignKeyField(Field):
    def __init__(self, model, key_field_name = 'id', *args, **kwargs):
        self.model = model
        self.key_field_name = key_field_name
        super(ForeignKeyField, self).__init__(*args, **kwargs)

    def clean(self, value):
        if value in fields.EMPTY_VALUES:
            return None
        result = self.model.objects.get(**{self.key_field_name : value })
        return result
